package com.flyinzhen.customer.service;

import com.flyinzhen.core.constants.ResponseStatus;
import com.flyinzhen.core.dto.ResponseDto;
import com.flyinzhen.core.service.RedisService;
import com.flyinzhen.core.utils.CommonUtils;
import com.flyinzhen.core.utils.HttpUtils;
import com.flyinzhen.customer.constants.RedisCacheType;
import com.flyinzhen.customer.constants.SmsTemplate;
import com.flyinzhen.customer.dto.input.SmsSendInput;
import com.flyinzhen.customer.interfaces.IFeignMessageService;
import com.flyinzhen.customer.properties.OperationProperties;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;

import static com.flyinzhen.customer.utils.ApplicationUtils.cacheKey;

/**
 * 用户认证实现类
 *
 * @author yinzhen
 * @date 2019-05-01
 */
@Slf4j
@Service
public class MessageService {

	@Resource
	private RedisService redisService;

	@Resource
	private IFeignMessageService feignMessageService;

	@Resource
	private OperationProperties operationProperties;

	public ResponseDto getCaptcha(String phone, String deviceId) {

		// 同一设备号或同一手机号每天发送验证码不超过5次，同一IP每天发送验证码不超过20次
		String ymdDate = DateFormatUtils.format(new Date(), "yyyyMMdd");
		String mobileTimesKey = cacheKey(RedisCacheType.CAPTCHA_TIMES.name(), ymdDate + "_" + phone);
		if (redisService.getLong(mobileTimesKey) >= operationProperties.getMobileSmsLimit()) {
			return ResponseDto.status(ResponseStatus.SMS_MOBILE_LIMIT);
		}
		redisService.incr(mobileTimesKey, 24 * 60 * 60);

		String ipTimesKey = cacheKey(RedisCacheType.CAPTCHA_TIMES.name(), ymdDate + "_" + HttpUtils.getRealIP());
		if (redisService.getLong(ipTimesKey) >= operationProperties.getIpSmsLimit()) {
			return ResponseDto.status(ResponseStatus.SMS_IP_LIMIT);
		}
		redisService.incr(ipTimesKey, 24 * 60 * 60);

		if (deviceId != null) {
			String deviceTimesKey = cacheKey(RedisCacheType.CAPTCHA_TIMES.name(), ymdDate + "_" + deviceId);
			if (redisService.getLong(deviceTimesKey) >= operationProperties.getDeviceSmsLimit()) {
				return ResponseDto.status(ResponseStatus.SMS_DEVICE_LIMIT);
			}
			redisService.incr(deviceTimesKey, 24 * 60 * 60);
		}

		// 先判断之前的验证码是否有效 有效则再次发送同样的
		String smsCaptcha = (String) redisService.get(cacheKey(RedisCacheType.CAPTCHA_SMS.name(), phone));
		if (StringUtils.isBlank(smsCaptcha)) {
			smsCaptcha = CommonUtils.createRandom(4, true);
		}

		// 发送验证码并更新缓存数据
		SmsSendInput inputDto = new SmsSendInput(phone, SmsTemplate.VERIFICATION_CODE.name(), new String[]{smsCaptcha});
		feignMessageService.sendSms(inputDto);
		redisService.put(cacheKey(RedisCacheType.CAPTCHA_SMS.name(), phone), smsCaptcha, 5 * 60);
		return ResponseDto.ok(smsCaptcha);
	}
}
